/***************************************************************************
 * 文件名：CentralPackageUtil
 * 功能：
 * 说明：
 * -------------------------------------------------------------------------
 * 创建时间：2025/7/14 10:50:21
 * 创建人：葛浩
 * 邮箱： 2094733071@qq.com
 * =========================================================================
 *
 * 修改人：   
 * 修改时间：   
 * 修改说明：   
 ***************************************************************************/
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace ReferenceManagement
{
	public class CentralPackageUtil
	{
		public CentralPackageUtil(CentralPackage package)
		{
			this.CentralPackage = package;
		}

		public CentralPackageUtil()
		{

		}

		public CentralPackage CentralPackage { get; set; }

		/// <summary>
		/// 加载文件
		/// </summary>
		/// <param name="fileName"></param>
		/// <returns></returns>
		/// <exception cref="IOException"></exception>
		public static CentralPackage LoadFile(string fileName)
		{
			if (!File.Exists(fileName))
			{
				throw new IOException($"文件{fileName}不存在");
			}

			var result = new CentralPackage(fileName);

			result.XDocument = XDocument.Load(fileName);
			result.Project = result.XDocument.DescendantNodes().OfType<XElement>().Where(p => string.Equals(p.Name.LocalName, "Project")).SingleOrDefault();
			var itemGroups = result.XDocument.Descendants().Where(p => string.Equals(p.Name.LocalName, "ItemGroup", StringComparison.OrdinalIgnoreCase)).ToList();

			result.ItemGroups = itemGroups;

			result.CustomPackages = new List<CSPackage>();
			result.OfficalPackages = new List<CSPackage>();
			result.OtherPackages = new List<CSPackage>();

			result.CustomPackages.AddRange(itemGroups[0]?.DescendantNodes().OfType<XElement>().Select(p => new CSPackage
			{
				PackageName = p.FirstAttribute?.Value,
				PackageVersion = p.FirstAttribute?.NextAttribute?.Value,
				Element = p,
			}));

			result.OfficalPackages.AddRange(itemGroups[1]?.DescendantNodes().OfType<XElement>().Select(p => new CSPackage
			{
				PackageName = p.FirstAttribute?.Value,
				PackageVersion = p.FirstAttribute?.NextAttribute?.Value,
				Element = p,
			}));

			result.OtherPackages.AddRange(itemGroups[2]?.DescendantNodes().OfType<XElement>().Select(p => new CSPackage
			{
				PackageName = p.FirstAttribute?.Value,
				PackageVersion = p.FirstAttribute?.NextAttribute?.Value,
				Element = p,
			}));

			return result;
		}

		/// <summary>
		/// 保存文件
		/// </summary>
		public static void Save(CentralPackage package)
		{
			if (package == null || package.XDocument == null)
			{
				return;
			}

			if (string.IsNullOrEmpty(package.DocumentFileName) || !File.Exists(package.DocumentFileName))
			{
				return;
			}

			package.XDocument.Save(package.DocumentFileName);
		}

		/// <summary>
		/// 具体实现
		/// </summary>
		/// <param name="packageName"></param>
		/// <param name="packageVersion"></param>
		/// <param name="itemType"></param>
		/// <returns></returns>
		/// <exception cref="ArgumentException"></exception>
		public CSPackage AddPackage(string packageName, string packageVersion, string itemType = "")
		{
			if (string.IsNullOrWhiteSpace(packageName))
			{
				throw new ArgumentException($"参数[包名称:{packageName}]不可为空！");
			}

			if (string.IsNullOrWhiteSpace(packageVersion))
			{
				throw new ArgumentException($"参数[包版本:{packageVersion}]不可为空！");
			}

			CSPackage pkgItem = new CSPackage();
			pkgItem.PackageName = packageName;
			pkgItem.PackageVersion = packageVersion;

			XElement newXElement = new XElement("PackageVersion");
			newXElement.SetAttributeValue("Include", packageName);
			newXElement.SetAttributeValue("version", packageVersion);

			pkgItem.Element = newXElement;

			XElement itemGroup = null;

			switch (itemType)
			{
				case ItemGroupTypeConst.A:
					if (CentralPackage.ItemGroups?.Count < 1)
					{
						itemGroup = new XElement("ItemGroup", newXElement);
						CentralPackage.Project.Add(itemGroup);
					}
					else
					{
						CentralPackage.ItemGroups[0].Add(newXElement);
					}
					break;
				case ItemGroupTypeConst.B:
					if (this.CentralPackage.ItemGroups?.Count < 2)
					{
						itemGroup = new XElement("ItemGroup", newXElement);
						this.CentralPackage.Project.Add(itemGroup);
					}
					else
					{
						this.CentralPackage.ItemGroups[1].Add(newXElement);
					}
					break;
				case ItemGroupTypeConst.C:
				default:
					if (this.CentralPackage.ItemGroups?.Count < 3)
					{
						itemGroup = new XElement("ItemGroup", newXElement);
						this.CentralPackage.Project.Add(itemGroup);
					}
					else
					{
						this.CentralPackage.ItemGroups[2].Add(newXElement);
					}
					break;
			}

			if (this.CentralPackage.EnableAutoSave)
			{
				Save(CentralPackage);
			}

			return pkgItem;
		}

		/// <summary>
		/// 移除名为packageName的包，默认移除第三方包
		/// </summary>
		/// <param name="packageName"></param>
		/// <param name="itemType"></param>
		/// <exception cref="ArgumentException"></exception>
		public void RemovePackage(string packageName, string itemType)
		{
			if (string.IsNullOrWhiteSpace(packageName))
			{
				throw new ArgumentException($"参数[包名称:{packageName}]不可为空！");
			}

			switch (itemType)
			{
				case ItemGroupTypeConst.A:
					{
						this.CentralPackage.CustomPackages
							.Where(p => string.Equals(p.PackageName, packageName, StringComparison.OrdinalIgnoreCase))
							.ToList()
							.ForEach(item =>
							{
								item.Element.Remove();
							});
						break;
					}
				case ItemGroupTypeConst.B:
					{
						this.CentralPackage.OfficalPackages
							.Where(p => string.Equals(p.PackageName, packageName, StringComparison.OrdinalIgnoreCase))
							.ToList()
							.ForEach(item =>
							{
								item.Element.Remove();
							});
						break;
					}
				case ItemGroupTypeConst.C:
				default:
					{
						this.CentralPackage.OtherPackages
							.Where(p => string.Equals(p.PackageName, packageName, StringComparison.OrdinalIgnoreCase))
							.ToList()
							.ForEach(item =>
							{
								item.Element.Remove();
							});
						break;
					}
			}
		}

		public bool Exists(string packageName, string itemType)
		{
			if (string.IsNullOrWhiteSpace(packageName))
			{
				return false;
			}

			switch (itemType)
			{
				case ItemGroupTypeConst.A:
					return this.CentralPackage.CustomPackages.Any(p => string.Equals(p.PackageName, packageName, StringComparison.OrdinalIgnoreCase));
				case ItemGroupTypeConst.B:
					return this.CentralPackage.OfficalPackages.Any(p => string.Equals(p.PackageName, packageName, StringComparison.OrdinalIgnoreCase));
				case ItemGroupTypeConst.C:
					return this.CentralPackage.OtherPackages.Any(p => string.Equals(p.PackageName, packageName, StringComparison.OrdinalIgnoreCase));
				default:
					return false;
			}
		}
	}
}
